package org.gokeep.communication.tcp;

import com.google.protobuf.ByteString;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.gokeep.communication.TestConfig;
import org.gokeep.communication.message.MessageBuilder;
import org.gokeep.communication.proto.CommandProto;
import org.gokeep.communication.proto.MessageProto;
import org.junit.jupiter.api.Test;
import org.smartboot.socket.StateMachineEnum;
import org.smartboot.socket.extension.processor.AbstractMessageProcessor;
import org.smartboot.socket.extension.protocol.ByteArrayProtocol;
import org.smartboot.socket.transport.AioQuickClient;
import org.smartboot.socket.transport.AioSession;
import org.smartboot.socket.transport.WriteBuffer;

import java.io.IOException;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.charset.Charset;
import java.util.Date;

@Slf4j
public class TcpClientDemo {
    @Test
    void testClient() throws InterruptedException {
        AbstractMessageProcessor<byte[]> messageProcessor = new AbstractMessageProcessor<>() {
            @SneakyThrows
            @Override
            public void process0(AioSession session, byte[] msg) {
                log.debug("收到消息: {}: ", new String(msg, Charset.defaultCharset()));
                MessageProto.Message message = MessageProto.Message.parseFrom(msg);
                if (message.getCommand().equals(CommandProto.CommandEnum.HEART)) {
                    log.info("收到心跳消息： {}", new Date());
                    WriteBuffer writeBuffer = session.writeBuffer();
                    MessageProto.Message.Builder ackBuilder = MessageBuilder.builder().initMessageBuilder(CommandProto.CommandEnum.HEART_ACK);
                    byte[] bytes = ackBuilder.build().toByteArray();
                    writeBuffer.writeInt(bytes.length);
                    writeBuffer.write(bytes);
                    writeBuffer.flush();
                }
            }

            @Override
            public void stateEvent0(AioSession session, StateMachineEnum stateMachineEnum, Throwable throwable) {
                log.debug("连接状态: {}", stateMachineEnum);
            }
        };
        AioQuickClient aioQuickClient = new AioQuickClient("localhost", TestConfig.TCP_SERVER_PORT, new ByteArrayProtocol(), messageProcessor);
        try {
            aioQuickClient.setReadBufferSize(102400);
            AioSession session = aioQuickClient.start(AsynchronousChannelGroup.withFixedThreadPool(2, Thread::new));
            WriteBuffer writeBuffer = session.writeBuffer();
            MessageProto.Message.Builder builder = MessageBuilder.builder().initMessageBuilder(CommandProto.CommandEnum.CHAT_REQUEST);
            builder.setToken("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHRlbmRJZCI6MSwidXNlcklkIjoxLCJjbGllbnRUeXBlIjoiUEMiLCJleHBpcmVfdGltZSI6LTEsInVzZXJuYW1lIjoieHVuaW5nIn0.9BAHnGtjcSDRrk7t3oaHL5LSPhoIDGULa7gS3hcy-Lw");
            String data = "3月6日这一天，我们邀请全国各地的朋友共同记录生活片段，并在上千个来稿中进行精选、集" +
                    "3月6日这一天，我们邀请全国各地的朋友共同记录生活片段，并在上千个来稿中进行精选、集" +
                    "结成片，同广大网友们共同创作了这部《中国一日》。每个人都是自己生活的导演，每个人的一日，共同写就了中国一日。";
            builder.setData(ByteString.copyFromUtf8(data));
            byte[] bytes = builder.build().toByteArray();
            int len = bytes.length;
            log.info("发送数据总长度： {}", len);
            writeBuffer.writeInt(len);
            writeBuffer.write(bytes);
            writeBuffer.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        Thread.sleep(200000);
    }
}
